package com.ruoyi.common.filter.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.filter.constants.GatewayConstant;
import org.springframework.http.HttpMethod;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;

/**
 * @description:
 * @author:
 * @date: 2021-08-16
 */
public class RequestUtils {

    /**
     * 获取请求头
     */
    public static TreeMap<String, Object> getRequestHeaderMap(HttpServletRequest request) {

        TreeMap<String, Object> headerMap = new TreeMap<>();
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_APP_ID, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_APP_ID));
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_SIGN, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_SIGN));
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_SIGN_TYPE, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_SIGN_TYPE));
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_CLIENT_TYPE, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_CLIENT_TYPE));
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_CLIENT_VERSION, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_CLIENT_VERSION));
        // TODO 后期增加根据时间戳防止重放攻击
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_TIMESTAMP, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_TIMESTAMP));

        // 添加非必填Header参数
        headerMap.put(GatewayConstant.REQ_HEAD_PARAM_EXTRA, request.getHeader(GatewayConstant.REQ_HEAD_PARAM_EXTRA));

        return headerMap;
    }

    /**
     * 将URL的参数和body参数合并
     *
     * @param request
     * @author show
     * @date 14:24 2019/5/29
     */
    public static SortedMap<String, Object> getAllParams(HttpServletRequest request) throws IOException {

        SortedMap<String, Object> result = new TreeMap<>();
        //获取URL上的参数
        Map<String, Object> urlParams = getUrlParams(request);
        for (Map.Entry entry : urlParams.entrySet()) {
            if (Objects.nonNull(entry.getValue())) {
                result.put((String) entry.getKey(), entry.getValue());
            }
        }
        Map<String, Object> allRequestParam = new HashMap<>(16);
        // get请求不需要拿body参数
        if (!HttpMethod.GET.name().equals(request.getMethod())) {
            allRequestParam = getAllRequestParam(request);
        }
        //将URL的参数和body参数进行合并
        if (allRequestParam != null) {
            for (Map.Entry entry : allRequestParam.entrySet()) {
                if (Objects.nonNull(entry.getValue())) {
                    result.put((String) entry.getKey(), entry.getValue());
                }

            }
        }
        return result;
    }
    /**
     * 判断JSON字符串是否是JSON对象
     *
     * @param json
     * @return
     */
    private static boolean isJsonObject(String json) {
        return json.trim().startsWith("{");
    }

    /**
     * 获取 Body 参数
     *
     * @param request
     * @author show
     * @date 15:04 2019/5/30
     */
    public static Map<String, Object> getAllRequestParam(final HttpServletRequest request) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String str = "";
        StringBuilder wholeStr = new StringBuilder();
        //一行一行的读取body体里面的内容；
        while ((str = reader.readLine()) != null) {
            wholeStr.append(str);
        }
        if ("".equals(wholeStr.toString())) {
            return new HashMap<>();
        } else {
            if (isJsonArray(wholeStr.toString())) {
                return null;
            } else if(isJsonObject(wholeStr.toString())) {
                //转化成json对象
                return JSONUtil.toBean(wholeStr.toString(), Map.class);
            }else {
                return null;
            }
        }
    }

    /**
     * 判断字符串是否可以转化为JSON数组
     *
     * @param content
     * @return
     */
    public static boolean isJsonArray(String content) {
        try {
            JSONArray jsonStr = JSONUtil.parseArray(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 将URL请求参数转换成Map
     *
     * @param request
     * @author show
     */
    public static Map<String, Object> getUrlParams(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<>(16);
        if (StrUtil.isNotEmpty(request.getQueryString())) {
            String param = "";
            try {
                param = URLDecoder.decode(request.getQueryString(), "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            String[] params = param.split("&");
            for (String s : params) {
                int index = s.indexOf("=");
                result.put(s.substring(0, index), s.substring(index + 1));
            }
        }
        return result;
    }

}
